package com.hyt.it.ogt.ks.service.canal.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.otter.canal.protocol.CanalEntry.Column;
import com.alibaba.otter.canal.protocol.CanalEntry.EventType;
import com.hyt.it.ogt.ks.config.canal.CanalTableEnum;
import com.hyt.it.ogt.ks.enums.log.AdminOperatorLogType;
import com.hyt.it.ogt.ks.enums.log.ApplyCheckState;
import com.hyt.it.ogt.ks.enums.log.LogEventType;
import com.hyt.it.ogt.ks.feign.es.EsClient;
import com.hyt.it.ogt.ks.model.entity.CandidateLogOther;
import com.hyt.it.ogt.ks.service.canal.CanalTableChangeHandlerService;
import com.hyt.it.ogt.ks.service.es.IEsAndDbService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 考生异常表处理服务
 * </p>
 *
 * @author zhoumiao
 * @since 2022-11-25
 */
@Service
@Slf4j
public class CanalCandidateLogOtherHandlerServiceImpl implements CanalTableChangeHandlerService {
    @Autowired
    private EsClient esClient;
    @Autowired
    private IEsAndDbService esAndDbService;

    @Override
    public void handle(List<Column> beforeColumns, List<Column> afterColumns, String dbName, String tableName, EventType eventType, long timestamp) {
        if (EventType.INSERT.equals(eventType)) {
            insert(beforeColumns, afterColumns, dbName, tableName, eventType, timestamp);
        } else if (EventType.DELETE.equals(eventType)) {
            delete(beforeColumns, afterColumns, dbName, tableName, eventType, timestamp);
        } else if (EventType.UPDATE.equals(eventType)) {
            update(beforeColumns, afterColumns, dbName, tableName, eventType, timestamp);
        }
    }

    @Override
    public void insert(List<Column> beforeColumns, List<Column> afterColumns, String dbName, String tableName, EventType eventType, long timestamp) {
        if (isExceptionManage(afterColumns) && isNeedRecordExceptionManage(afterColumns)) {
            // 只处理异常管理类型并且需要记录的异常管理
            String id = getFieldValue(afterColumns, "id");
            esAndDbService.saveOrUpdateCandidateLogOtherById(id);
        }
    }

    /**
     * 是否需要记录的异常管理
     *
     * @param columns
     * @return
     */
    private boolean isNeedRecordExceptionManage(List<Column> columns) {
        String dbEventType = getFieldValue(columns, "operate_type");
        if (Objects.equals(AdminOperatorLogType.ID_CHECK_PASSED.getCode() + "", dbEventType)
                || Objects.equals(AdminOperatorLogType.DEVICE_CHECK_PASSED.getCode() + "", dbEventType)) {
            String operateContentJson = getFieldValue(columns, "operate_content");
            CandidateLogOther.OperateContent operateContent = JSON.parseObject(operateContentJson, CandidateLogOther.OperateContent.class);
            Integer applyResult = operateContent.getApplyResult();
            if (Objects.equals(ApplyCheckState.NO_PASSED.getCode(), applyResult)) {
                // 审核不通过的人脸跳过申请和设备检测跳过申请不需要记录
                return true;
            }
        } else if (Objects.equals(String.valueOf(AdminOperatorLogType.CANCEL_OPEN_TIMEING.getCode()), dbEventType)) {
            //这种是p4新加的单题限制时长，考生被重置时长的操作
            return Boolean.TRUE;
        }
        return !Objects.equals(dbEventType, AdminOperatorLogType.FINISH_ALL_EXAM.getCode() + "");
    }

    @Override
    public void delete(List<Column> beforeColumns, List<Column> afterColumns, String dbName, String tableName, EventType eventType, long timestamp) {
        if (isExceptionManage(beforeColumns)) {
            String id = getFieldValue(beforeColumns, "id");
            esClient.delete(Collections.singletonList(id));
        }
    }

    @Override
    public void update(List<Column> beforeColumns, List<Column> afterColumns, String dbName, String tableName, EventType eventType, long timestamp) {
        if (isExceptionManage(afterColumns)) {
            String id = getFieldValue(afterColumns, "id");
            esAndDbService.saveOrUpdateCandidateLogOtherById(id);
        }
    }

    @Override
    public String getHandleTableName() {
        return CanalTableEnum.KS_CANDIDATE_LOG_OTHER.getTable();
    }

    private boolean isExceptionManage(List<Column> columns) {
        String dbEventType = getFieldValue(columns, "event_type");
        return Objects.equals(dbEventType, LogEventType.EXAMINATION_LOG.getCode() + "");
    }
}
